package cn.turboinfo.dongying.api.gateway.admin.controller.dictconfig;

import cn.turboinfo.dongying.api.domain.admin.usecase.dictconfig.*;
import cn.turboinfo.dongying.api.domain.util.BeanHelper;
import cn.turboinfo.dongying.api.entity.common.pojo.dictconfig.DictConfigItem;
import cn.turboinfo.dongying.api.entity.common.pojo.dictconfig.QDictConfigItem;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemCreateFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemSearchFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemUpdateFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.ResponseBodyWrapper;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.RestResponseFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemCreateFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemSearchFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.dictconfig.DictConfigItemUpdateFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.ResponseBodyWrapper;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.RestResponseFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.request.QSort;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanSearchHelper;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

@Slf4j
@RequiredArgsConstructor
@Controller
@ResponseBodyWrapper
@RequestMapping("/admin/dictConfig")
public class DictConfigItemController {
    private final DictConfigItemSearchUseCase dictConfigItemSearchUseCase;

    private final DictConfigItemCreateUseCase dictConfigItemCreateUseCase;

    private final DictConfigItemUpdateUseCase dictConfigItemUpdateUseCase;

    private final DictConfigItemDeleteUseCase dictConfigItemDeleteUseCase;

    private final DictConfigItemCheckAvailableUseCase dictConfigItemCheckAvailableUseCase;

    private final DictConfigItemByDictConfigKeyUseCase dictConfigItemByDictConfigKeyUseCase;

    @RequestMapping("/item/list")
    public RestResponseFO list(@Valid @NotNull @RequestParam String dictConfigKey) {

        DictConfigItemByDictConfigKeyUseCase.OutputData outputData = dictConfigItemByDictConfigKeyUseCase.execute(DictConfigItemByDictConfigKeyUseCase.InputData
                .builder()
                .dictConfigKey(dictConfigKey)
                .build()
        );

        return RestResponseFO.ok(outputData.getDictConfigItemList());
    }

    @RequiresPermissions("dictConfigItem:list")
    @RequestMapping("/{dictConfigId}/list")
    public LimitDataFO<DictConfigItem> list(@PathVariable Long dictConfigId, @Valid DictConfigItemSearchFO search, LimitFO page,
                                            SortFO sort) {
        QRequest request = QBeanSearchHelper.convertQRequest(search);
        request.filterEqual(QDictConfigItem.dictConfigId, dictConfigId);

        if (sort.getSortFields() == null) {
            sort.setSortFields(new String[]{QDictConfigItem.id + "|" + QSort.Order.DESC.name()});
        }

        DictConfigItemSearchUseCase.OutputData outputData = dictConfigItemSearchUseCase.execute(DictConfigItemSearchUseCase.InputData
                .builder()
                .request(request)
                .requestPage(page.toQPage(sort.toQSortList()))
                .build());

        return LimitDataFO.fromQResponse(outputData.getQResponse());
    }

    @RequiresPermissions("dictConfigItem:create")
    @PostMapping("/{dictConfigId}/create")
    public RestResponseFO create(@PathVariable Long dictConfigId, @RequestBody @Valid DictConfigItemCreateFO request) {
        DictConfigItemCreateUseCase.InputData.InputDataBuilder inputDataBuilder = DictConfigItemCreateUseCase.InputData.builder();

        BeanHelper.copyPropertiesToBuilder(inputDataBuilder, DictConfigItemCreateFO.class, request);

        DictConfigItemCreateUseCase.OutputData outputData = dictConfigItemCreateUseCase
                .execute(inputDataBuilder
                        .dictConfigId(dictConfigId)
                        .build());

        return RestResponseFO.ok(outputData);
    }

    @RequiresPermissions("dictConfigItem:update")
    @PostMapping("/{dictConfigId}/update")
    public RestResponseFO update(@PathVariable Long dictConfigId, @RequestBody @Valid DictConfigItemUpdateFO request) {
        DictConfigItemUpdateUseCase.InputData.InputDataBuilder inputDataBuilder = DictConfigItemUpdateUseCase.InputData.builder();

        BeanHelper.copyPropertiesToBuilder(inputDataBuilder, DictConfigItemUpdateFO.class, request);

        DictConfigItemUpdateUseCase.OutputData outputData = dictConfigItemUpdateUseCase
                .execute(inputDataBuilder
                        .dictConfigId(dictConfigId)
                        .build());

        return RestResponseFO.ok(outputData);
    }

    @RequiresPermissions("dictConfigItem:delete")
    @PostMapping("/{dictConfigId}/delete")
    @ResponseBody
    public RestResponseFO delete(@PathVariable Long dictConfigId, @Valid @NotNull @RequestParam Long id) {
        dictConfigItemDeleteUseCase
                .execute(DictConfigItemDeleteUseCase.InputData.builder()
                        .dictConfigItemId(id)
                        .build());
        return RestResponseFO.ok();
    }

    @RequiresPermissions("dictConfigItem:list")
    @ResponseBody
    @GetMapping(value = "/{dictConfigId}/checkAvailable")
    public boolean checkAvailable(@PathVariable Long dictConfigId, @RequestParam String itemValue, @RequestParam(required = false) Long id) {
        DictConfigItemCheckAvailableUseCase.OutputData outputData = dictConfigItemCheckAvailableUseCase.execute(DictConfigItemCheckAvailableUseCase.InputData
                .builder()
                .dictId(dictConfigId)
                .itemId(id)
                .itemValue(itemValue)
                .build());

        return outputData.isAvailable();
    }
}
